﻿using System;
using System.Linq;
using Reviewer.Entities;
using Reviewer.Entities.Services;
using System.Collections.Generic;
using System.Threading;
using System.Collections.ObjectModel;
using System.Globalization;

namespace Reviewer.Business.Services
{
    /// <summary>
    /// Review Service
    /// </summary>
    internal class ReviewService : BaseService, IReviewService, IReviewAdminService
    {
        internal ReviewService() : base() { }

        #region methods (public)
        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            GC.SuppressFinalize(this);
        }

        public Collection<Review> Find()
        {
            return new Data.ReviewRepository().SelectAll();
        }

        public Reviewer.Entities.Review Find(int id)
        {
            if (id < 1)
            {
                throw new ArgumentOutOfRangeException("id", "Invalid key identifier");
            }

            return new Data.ReviewRepository().SelectBy(id);
        }

        public Collection<Review> FindByGameId(Int32 gameId)
        {
            if (gameId <= 0)
            {
                throw new ArgumentOutOfRangeException("gameId", "Invalid key identifier");
            }

            return new Data.ReviewRepository().SelectByAlternateKey(gameId);
        }

        public Collection<Review> FindLatest(int topCount)
        {
            return new Data.ReviewRepository().SelectLatest(topCount);
        }

        public Collection<ReviewSearchResult> Search(String gameTitle, Int32? gameFormat, Int32? gameGenre, Int32? reviewAuthor, Int32? distributor, Int32? maxResults)
        {
            return new Data.ReviewRepository().Search(gameTitle, gameFormat, gameGenre, reviewAuthor, distributor, maxResults);
        }
        #endregion

        #region IReviewAdminService Members
        public Reviewer.Entities.Review Save(Reviewer.Entities.Review ReviewItem)
        {
            ReviewItem.LastModifiedDate = DateTime.Now;
            if (ReviewItem.Id < 1)
            {
                Review newItem = new Data.ReviewRepository().Create(ReviewItem);

                #region Add FrontPage Post
                FrontPagePost post = new FrontPagePost();
                post.PostType = "REVIEW";
                if (newItem.Header.Length > 150)
                {
                    post.Text = newItem.Header.Substring(0, 150) + "...";
                }
                else
                {
                    post.Text = newItem.Header;
                }

                Game game = ServiceFactory.GameService.GetBy(newItem.GameId);
                Format format = ServiceFactory.GetMetadataService<Format>().GetAll().First(t => t.Id.Equals(game.Format));
                post.Title = String.Format(CultureInfo.InvariantCulture, "{0} ({1})", game.Title, format != null ? format.Name : "Ukendt format");
                post.Link = newItem.Id.ToString(CultureInfo.InvariantCulture);
                post.Date = DateTime.Now.Date;
                ServiceFactory.FrontPagePostAdminService.Save(post);
                #endregion

                return newItem;
            }

            return new Data.ReviewRepository().Update(ReviewItem);
        }

        public bool Delete(Reviewer.Entities.Review ReviewItem)
        {
            return this.DeleteById(ReviewItem.Id);
        }

        public bool DeleteById(int id)
        {
            new Data.ReviewRepository().Delete(id);
            return true;
        }

        public bool DeleteByGameId(int gameId)
        {
            foreach (Review review in this.Find())
            {
                if (review.GameId.Equals(gameId))
                {
                    this.DeleteById(review.Id);
                }
            }
            return true;
        }

        #endregion
    }
}
